const puppeteer = require('puppeteer');
const commSession = require('../platform/CommSession');
const _static = require('../base/static');
const Api = require('../base/api');
const commUtil = require('../base/utils');
const fsPath = require('path');

class Session {

    constructor(selector, headless = true) {
        return new Promise(async (resolve, reject) => {
            if (selector == null) {
                reject('empty selector')
            }
            this.username = "zhaobiji";
            this.password = "Zhaobiji1";
            this.config = {
                env : "PRO",
                connect: '晋游码',
                db : 'jtour_moments',
                remark: '点评',
                qaUser : 'admin',
                sql: 'SELECT * FROM COMMENT ORDER BY id DESC LIMIT 5'
            };
            // 验证码
            this.codeFile = `cookies/${this.username}-code.png`;
            this.selector = selector;
            this.savePath = fsPath.join(__dirname) + "/sqlSession_jwt.txt";
            this.browser = await puppeteer.launch({
                args: ['--no-sandbox', '--disable-setuid-sandbox',
                    '--disable-gpu', '--disable-dev-shm-usage',
                    '--no-first-run', '--no-zygote', '--unhandled-rejections=strict'],
                headless: headless,
                slowMo: 20,
                defaultViewport: {
                    width: 1024,
                    height: 800
                }
            }).catch(reason => reject(reason));
            return resolve(this);
        })
    }

    async login() {
        // let jwtValue = commUtil.readFile(this.savePath);
        // jwtValue = jwtValue.toString();
        let page = await this.initPage();
        this.page = page;
        // await page.goto(this.selector.loginUrl, {waitUntil: 'networkidle0'});
        // await page.evaluate((jwtV) => {
        //     window.sessionStorage.setItem('jwt', jwtV);
        //     window.sessionStorage.setItem('hasGreet', '1');
        //     window.sessionStorage.setItem('real_name', '赵比基');
        //     window.sessionStorage.setItem('access', '1');
        //     window.sessionStorage.setItem('auth', 'guest');
        //     window.sessionStorage.setItem('user', 'zhaobiji');
        // }, jwtValue);
        // await page.goto(this.selector.homeUrl, {waitUntil: 'networkidle0'});
        // await page.waitFor(_static.twoT);
        // let url = await page.url();
        // if (this.selector.homeUrl === url.toString()) {
        //     return true;
        // }
        await page.goto(this.selector.loginUrl, {waitUntil: 'networkidle0'});
        await commSession.oneStepT(page, this.selector.login.username, this.username);
        await commSession.oneStepT(page, this.selector.login.password, this.password);

        for (let i = 0; i < 5; i++) {
            let codeTrue = await this.getYzm(page);
            if (codeTrue === true) {
                return true;
            }
            await page.waitFor(_static.oneT);
        }
        return false;
    }

    async getYzm(page) {
        //调用evaluate 方法返回id 为form元素的位置信息
        let clip = await page.evaluate((yzmId) => {
            let {
                x, y, width, height
            } = document.querySelector(yzmId).getBoundingClientRect();
            return {x, y, width, height};
        }, this.selector.login.yzmPhoto);
        // 官方说明 ：截屏 这个过程可能需要1~6秒
        await page.screenshot({
            path: this.codeFile,
            type: 'jpeg',
            quality: 80,
            clip: clip,
        });
        await page.waitFor(_static.threeT);
        let yzm = await Api.method.yzmCode(this.codeFile);
        console.log("验证码：" + yzm);
        await commSession.oneStepT(page, this.selector.login.yzmCode, yzm, _static.twoT);
        await commSession.oneStepC(page, this.selector.login.submit);
        await page.waitFor(_static.twoT);
        let url = await page.url();
        if (this.selector.homeUrl === url.toString()) {
            let pageSession = await page.evaluate(() => {
                return {jwt : window.sessionStorage.getItem('jwt')};
            });
            let savePath = fsPath.join(__dirname) + "/sqlSession_jwt.txt";
            commUtil.writeFile(pageSession.jwt.toString(), savePath);
            await page.waitFor(_static.twoT);
            commUtil.readFile(savePath);
            return true;
        }
        await commSession.oneStepC(page, this.selector.login.yzmCode);
        await commSession.mouseExecutor(page, "Backspace", 8);
        return false;
    }

    async close() {
        await this.browser.close()
    }

    async initPage() {
        let page = await this.browser.newPage();
        let _window = await page.evaluate(() => {
            return {width : window.screen.width, height : window.screen.height};
        });
        page.setViewport({
            width: _window.width,
            height: _window.height
        });
        await page.waitFor(_static.oneT);
        return page;
    }

    async execute(){
        let page = this.page;
        await page.goto(this.selector.ddlUrl, {waitUntil: 'networkidle0'});
        // 环境
        await commSession.oneStepC(page, this.selector.environment);
        await this.clickTarget(page, this.config.env, this.selector.envChildLi);
        // 连接名
        await commSession.oneStepC(page, this.selector.connect);
        await this.clickTarget(page, this.config.connect, this.selector.connectLi);
        // 数据库
        await commSession.oneStepC(page, this.selector.db);
        await this.clickTarget(page, this.config.db, this.selector.dbLi);
        // 说明
        await commSession.oneStepT(page, this.selector.remark, this.config.remark);
        // 审核人
        await commSession.oneStepC(page, this.selector.qaUser);
        await this.clickTarget(page, this.config.qaUser, this.selector.qaUserLi);
        // sql
        await commSession.oneStepT(page, this.selector.sql, this.config.sql, _static.oneT);
    }

    async clickTarget(page, text, fatherEle) {
        let nodes = await page.$$(fatherEle);
        for (let i = 1; i <= nodes.length; i++) {
            let uiEle = fatherEle + ':nth-child('+i+')';
            let optionText = await commSession.getText(page, uiEle);
            if (optionText === text) {
                await commSession.oneStepC(page, uiEle);
                break;
            }
        }
    }

}


module.exports = Session;